#ifndef __ITIPS_H__
#define __ITIPS_H__

#include "astro.h"
#include "base.pb.h"
#include "cam_tele.h"
#include "focus.h"
#include "system.h"
#include "motor_controller.h"

#include <iostream>
#include <sstream>
#include <string>

enum AppMode {
    ASTRO_MODE = 1,
    PHOTO_MODE,
    VIDEO_MODE,
    PANO_MODE,
    TIMELAPSE_MODE,
    BURST_MODE
};

enum StepId {
    ASTRO_DARK = 1,
    ASTRO_FOCUS,
    ASTRO_CALIBRATION,
    ASTRO_GOTO,
    ASTRO_ADJUST_PARAMS,
    ASTRO_LIVE_STACKING,
};

enum ITipsStatus {
    DONE = 1,
    ERROR,
    WARNING,
    UNDONE,
};

// struct 

class ITipsCode {
public:
    ITipsCode(int mode, int interface, int code) {
        std::ostringstream result;
        result << std::setfill('0') << std::setw(2) << mode;
        result << std::setfill('0') << std::setw(4) << interface;
        result << std::setfill('0') << std::setw(4) << code;
        itips_code = result.str();
    }

    inline std::string getITipsCode() const { 
        std::cout << "itips_code: " << itips_code << std::endl;
        return itips_code; 
    }

private:
    std::string itips_code;
};

class ITips {
private:
    CamTele cam_tele_;
    Focus focus_;
    Astro& astro_ = Astro::astro();
    System system_;
    StepMotorUser& motor_yaw_ = MotorController::motorYaw();
    StepMotorUser& motor_pitch_ = MotorController::motorPitch();

    // 天文模式错误码
    int old_astro_mode_cmd_id_ = 0;
    int old_astro_mode_error_code_ = 0;
    int astro_mode_cmd_id_ = 0;
    int astro_mode_error_code_ = 0;

    // 拍照模式错误码
    int old_photo_mode_cmd_id_ = 0;
    int old_photo_mode_error_code_ = 0;
    int photo_mode_cmd_id_ = 0;
    int photo_mode_error_code_ = 0;

    // 录像模式错误码
    int old_video_mode_cmd_id_ = 0;
    int old_video_mode_error_code_ = 0;
    int video_mode_cmd_id_ = 0;
    int video_mode_error_code_ = 0;

    // 全景模式错误码
    int old_pano_mode_cmd_id_ = 0;
    int old_pano_mode_error_code_ = 0;
    int pano_mode_cmd_id_ = 0;
    int pano_mode_error_code_ = 0;

    // 延时摄影模式错误码
    int old_timelapse_mode_cmd_id_ = 0;
    int old_timelapse_mode_error_code_ = 0;
    int timelapse_mode_cmd_id_ = 0;
    int timelapse_mode_error_code_ = 0;

private:
    ITips() {
        astro_.addITipsObserver(this);
        focus_.addITipsObserver(this);
    }

    int getStarLastProcedureCmd(int cmd_id);
    int getSunMoonLastProcedureCmd(int cmd_id);

public:
    static ITips& itips() { 
        static ITips itips;  
        return itips;
    }

    int handleMessage(WsPacket& ws_packet);
	
    int getITips(WsPacket& ws_packet);

    int getAstroITips();
    int getAstroITips(int astro_mode_cmd_id, int astro_mode_error_code);

    int updateCmdIdAndErrorCode(int cmd_id, int error_code);
    int backToOldCmdIdAndErrorCode(int cmd_id);
    int getErrorCode(int cmd_id);
};

#endif